home *** CD-ROM | disk | FTP | other *** search
/ Aminet 39 / Aminet 39 (2000)(Schatztruhe)[!][Oct 2000].iso / Aminet / game / shoot / Orbit_src.lha / Orbit / source / missile.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-04  |  8.8 KB  |  444 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5.     22.06.2000 - DrawMissile0/1/3() optimized (double to float)
  6. */
  7. /*
  8.  
  9. ORBIT, a freeware space combat simulator
  10. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  11.  
  12. This program is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU General Public License
  14. as published by the Free Software Foundation; either version 2
  15. of the License, or (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program; if not, write to the Free Software
  24. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  25.  
  26. */
  27.  
  28. #include "orbit.h"
  29.  
  30. void InitMissiles()
  31. /*
  32.  *  Set up missile structures
  33.  */
  34. {
  35.   int i;
  36.  
  37.   /* Mark all missiles as unused */
  38.   for (i=0; i<NMSLS; i++)
  39.   {
  40.     msl[i].age = 0.0;
  41.   }
  42. }
  43.  
  44. int FindMissile()
  45. /*
  46.  *  Find unused missile
  47.  */
  48. {
  49.   int i, oldest;
  50.   double maxage;
  51.  
  52.   /* Look for free missile, or oldest */
  53.   for (i=0; i<NMSLS; i++)
  54.   {
  55.     if (msl[i].age == 0.0) return (i);
  56.  
  57.     if (i == 0)
  58.     {
  59.       maxage = msl[i].age;
  60.       oldest = i;
  61.     }
  62.     else
  63.     {
  64.       if (msl[i].age > maxage)
  65.       {
  66.         maxage = msl[i].age;
  67.         oldest = i;
  68.       }
  69.     }
  70.   }
  71.  
  72.   /* None free, return oldest */
  73.   return (oldest);
  74. }
  75.  
  76. void FireMissile (double *pos, double *vel, double *dir, int friendly, int wep, int owner)
  77. /*
  78.  *  Fire missile at the given location and velocity, in
  79.  *  the specified direction
  80.  */
  81. {
  82.   int m;
  83.   double v[3];
  84.  
  85.   /* Find a free missile */
  86.   m = FindMissile();
  87.  
  88.   /* Set it up */
  89.   msl[m].age = deltaT;
  90.   Vset (msl[m].pos, pos);
  91.  
  92.   if (friendly && !am_client && !am_server)
  93.   {
  94.     Vmul (v, player.up, -0.005);
  95.     Vadd (msl[m].pos, msl[m].pos, v);
  96.   }
  97.  
  98.   Vmul (msl[m].vel, dir, weapon[wep].speed);
  99.   Vadd (msl[m].vel, msl[m].vel, vel);
  100.  
  101.   msl[m].friendly = friendly;
  102.   msl[m].weapon = wep;
  103.   msl[m].owner = owner;
  104.  
  105.   /* Play the sound */
  106.   /* if (sound) PlaySound ("phaser.wav", NULL, SND_ASYNC | SND_FILENAME); */
  107.   if (sound) PlayAudio (SOUND_FIRE);
  108. }
  109.  
  110. void MoveMissiles()
  111. /*
  112.  *  Move all the missiles
  113.  */
  114. {
  115.   int m, t, p;
  116.   double v[3], deltav[3];
  117.  
  118.   /* Loop through missiles */
  119.   for (m=0; m<NMSLS; m++)
  120.   {
  121.     /* If missile in use */
  122.     if (msl[m].age > 0.0)
  123.     {
  124.       /* Bump age */
  125.       msl[m].age += deltaT;
  126.  
  127.       /* See if expired */
  128.       if (msl[m].age > weapon[msl[m].weapon].expire)
  129.       {
  130.         DestroyMissile (m);
  131.         return;
  132.       }
  133.  
  134.       /* See if missile has hit planet */
  135.       if ((-1) != (p = InsidePlanet (msl[m].pos)))
  136.       {
  137.         /* Missile has hit planet */
  138.  
  139.         /* Move point of impact just above planet surface */
  140.         Vsub (v, msl[m].pos, planet[p].pos);
  141.         Normalize (v);
  142.         Vmul (v, v, planet[p].radius*1.05);
  143.         Vadd (v, v, planet[p].pos);
  144.         Boom (v, weapon[msl[m].weapon].yield/100.0);
  145.         DestroyMissile (m);
  146.         return;
  147.       }
  148.  
  149.       /* See if missile hit a target */
  150.       if ((-1) != (t = HitTarget (m)))
  151.       {
  152.         /* Missle hit target */
  153.         MissileHitTarget (m, t);
  154.         return;
  155.       }
  156.  
  157.       /* See if missile hit player */
  158.       if (!msl[m].friendly && !am_client && 
  159.       (state != STATE_DEAD1) && (state != STATE_DEAD2) )
  160.       {
  161.         if (TARGDIST2 > Dist2 (msl[m].pos[0], msl[m].pos[1], msl[m].pos[2],
  162.         player.pos[0], player.pos[1], player.pos[2]))
  163.         {
  164.           /* Missile hit player */
  165.           MissileHitPlayer (m);
  166.           return;
  167.         }
  168.       }
  169.       
  170.       /* Else update its position */
  171.       if (gravity)
  172.       {
  173.         Gravity (deltav, msl[m].pos);
  174.         Vadd (msl[m].vel, msl[m].vel, deltav);
  175.       }
  176.       Vmul (v, msl[m].vel, deltaT);
  177.       Vadd (msl[m].pos, msl[m].pos, v);
  178.     }
  179.   }
  180. }
  181.  
  182. void DestroyMissile (int m)
  183. /*
  184.  *  Missile has expired 
  185.  */
  186. {
  187.   msl[m].age = 0.0;
  188. }
  189.  
  190. void DrawMissiles ()
  191. /*
  192.  *  Draw all the missiles
  193.  */
  194. {
  195.   int m;
  196.  
  197.   for (m=0; m<NMSLS; m++)
  198.   {
  199.     if (msl[m].age > 0.0) DrawMissile (m);
  200.   }
  201. }
  202.  
  203. void DrawMissile (int m)
  204. /*
  205.  *  Draw this missile
  206.  */
  207. {
  208.   glPushMatrix();
  209.   glDisable (GL_LIGHTING);
  210.   glDisable (GL_CULL_FACE);
  211.  
  212.   switch (weapon[msl[m].weapon].renderer)
  213.   {
  214.     case 0: DrawMissile0 (m);
  215.     break;
  216.  
  217.     case 1: DrawMissile1 (m);
  218.     break;
  219.  
  220.     case 2: DrawMissile2 (m);
  221.     break;
  222.  
  223.     case 3: DrawMissile3 (m);
  224.     break;
  225.  
  226.     case 4: DrawMissile4 (m);
  227.     break;
  228.   }
  229.  
  230.   glEnable (GL_CULL_FACE);
  231.   glEnable (GL_LIGHTING);
  232.   glPopMatrix();
  233. }
  234.  
  235. void DrawMissile0 (int m)
  236. {
  237.   float r;
  238.   double v[3];
  239.  
  240.   /* Figure how much to spin missile */
  241.   r = (float)absT - ((float)(int)absT);
  242.   r *= 360.0;
  243.  
  244.   glColor3fv (weapon[msl[m].weapon].color);
  245.  
  246.   Vsub (v, msl[m].pos, player.pos);
  247.   glTranslated (v[0], v[1], v[2]);
  248.   glRotatef (r, 0.3, 1.0, 0.6);
  249.  
  250.   glBegin (GL_LINES);
  251.   glVertex3f (-0.01, 0.0, 0.0);
  252.   glVertex3f ( 0.01, 0.0, 0.0);
  253.   glVertex3f (0.0, -0.01, 0.0);
  254.   glVertex3f (0.0,  0.01, 0.0);
  255.   glVertex3f (0.0, 0.0, -0.01);
  256.   glVertex3f (0.0, 0.0,  0.01);
  257.   glEnd();
  258. }
  259.  
  260. void DrawMissile1 (int m)
  261. {
  262.   float r;
  263.   double v[3];
  264.  
  265.   /* Figure how much to spin missile */
  266.   r = (float)absT - ((float)(int)absT);
  267.   r *= 360.0;
  268.  
  269.   glColor3fv (weapon[msl[m].weapon].color);
  270.  
  271.   Vsub (v, msl[m].pos, player.pos);
  272.   glTranslated (v[0], v[1], v[2]);
  273.   glRotatef (r, 0.3, 1.0, 0.6);
  274.  
  275.   glBegin (GL_LINES);
  276.   glVertex3f (-0.01, 0.0, 0.0);
  277.   glVertex3f ( 0.01, 0.0, 0.0);
  278.   glVertex3f (0.0, -0.01, 0.0);
  279.   glVertex3f (0.0,  0.01, 0.0);
  280.   glVertex3f (0.0, 0.0, -0.01);
  281.   glVertex3f (0.0, 0.0,  0.01);
  282.   glEnd();
  283. }
  284.  
  285. void DrawMissile2 (int m)
  286. {
  287.   double v1[3], v2[3], v3[3], v4[4], vel[3], v[3];
  288.  
  289.   glColor3fv (weapon[msl[m].weapon].color);
  290.  
  291.   Vsub (v, msl[m].pos, player.pos);
  292.   glTranslated (v[0], v[1], v[2]);
  293.  
  294.   Vmul (vel, msl[m].vel, 0.1);
  295.  
  296.   glBegin (GL_QUADS);
  297.  
  298.   v1[0] =  0.01; v1[1] = 0.0; v1[2] = 0.0;
  299.   v2[0] = -0.01; v2[1] = 0.0; v2[2] = 0.0;
  300.   Vsub (v3, v2, vel);
  301.   Vsub (v4, v1, vel);
  302.   glVertex3dv (v1);
  303.   glVertex3dv (v2);
  304.   glVertex3dv (v3);
  305.   glVertex3dv (v4);
  306.  
  307.   v1[0] = 0.0; v1[1] =  0.01; v1[2] = 0.0;
  308.   v2[0] = 0.0; v2[1] = -0.01; v2[2] = 0.0;
  309.   Vsub (v3, v2, vel);
  310.   Vsub (v4, v1, vel);
  311.   glVertex3dv (v1);
  312.   glVertex3dv (v2);
  313.   glVertex3dv (v3);
  314.   glVertex3dv (v4);
  315.  
  316.   v1[0] = 0.0; v1[1] = 0.0; v1[2] =  0.01;
  317.   v2[0] = 0.0; v2[1] = 0.0; v2[2] = -0.01;
  318.   Vsub (v3, v2, vel);
  319.   Vsub (v4, v1, vel);
  320.   glVertex3dv (v1);
  321.   glVertex3dv (v2);
  322.   glVertex3dv (v3);
  323.   glVertex3dv (v4);
  324.  
  325.   glEnd();
  326. }
  327.  
  328. void DrawMissile3 (int m)
  329. {
  330.   float r;
  331.   double v[3];
  332.  
  333.   /* Figure how much to spin missile */
  334.   r = (float)absT - ((float)(int)absT);
  335.   r *= 360.0;
  336.  
  337.   glColor3fv (weapon[msl[m].weapon].color);
  338.  
  339.   Vsub (v, msl[m].pos, player.pos);
  340.   glTranslated (v[0], v[1], v[2]);
  341.   glRotatef (r, 0.3, 1.0, 0.6);
  342.   glScalef (0.01, 0.01, 0.01);
  343.  
  344.   glutSolidTetrahedron ();
  345. }
  346.  
  347. void DrawMissile4 (int m)
  348. {
  349.   int i;
  350.   double v[3], u[3];
  351.  
  352.   glColor3fv (weapon[msl[m].weapon].color);
  353.  
  354.   Vsub (u, msl[m].pos, player.pos);
  355.   glTranslated (u[0], u[1], u[2]);
  356.  
  357.   glBegin (GL_LINE_LOOP);
  358.   for (i=0; i<6; i++)
  359.   {
  360.     v[0] = rnd(0.04) - 0.01;
  361.     v[1] = rnd(0.04) - 0.01;
  362.     v[2] = rnd(0.04) - 0.01;
  363.     glVertex3dv (v);
  364.   }
  365.   glEnd();
  366. }
  367.  
  368. void MissileHitPlayer (int m)
  369. /*
  370.  *  Missile m hit player.  Ouch!
  371.  */
  372. {
  373.   /* Flash screen red */
  374.   palette_flash = 2;
  375.  
  376.   /* Damage shields */
  377.   player.shields -= weapon[msl[m].weapon].yield;
  378.  
  379.   /* Get rid of missile */
  380.   DestroyMissile (m);
  381.  
  382.   /* See if player died */
  383.   if (vulnerable && (player.shields < 0.0) && !am_client)
  384.   {
  385.     if (am_server) 
  386.     {
  387.       /* Tell other clients */ 
  388.       NetDestroyClient (server.client, FindClientByTarget (msl[m].owner)); 
  389.       NetPlayerDies(); 
  390.     }
  391.     else 
  392.     {
  393.       /* Single player games, reset */
  394.       InitPlayer();
  395.       ReadMission (mission.fn);
  396.       Mprint ("You were killed!  Restarting mission."); 
  397.     }
  398.   }
  399.  
  400.   if (player.shields < 0.0) player.shields = 100.0;
  401. }
  402.  
  403. void MissileHitTarget (int m, int t)
  404. /*
  405.  *  Missile m hit target t.  Go get 'em!
  406.  */
  407. {
  408.   int e;
  409.  
  410.   Boom (msl[m].pos, weapon[msl[m].weapon].yield/100.0);
  411.  
  412.   target[t].shields -= weapon[msl[m].weapon].yield;
  413.   if (target[t].shields < 0.0) target[t].shields = 0.0;
  414.  
  415.   /* Announce to network */
  416.   if (am_server) NetHitTarget (t, m);
  417.  
  418.   /* See if we set off an event */
  419.   for (e=0; e<NEVENTS; e++)
  420.   {
  421.     if (event[e].pending &&
  422.     event[e].enabled &&
  423.     (event[e].trigger == EVENT_SHIELDS) &&
  424.     (!strcasecmp (event[e].cvalue, target[t].name)) &&
  425.     (target[t].shields <= event[e].fvalue) )
  426.     {
  427.       EventAction (e);
  428.     }
  429.   }
  430.  
  431.   /* See if target is destroyed */
  432.   if (!am_client && target[t].shields <= 0.0)
  433.   {
  434.     /* Announce to network */
  435.     NetDestroyTarget (t, m);
  436.  
  437.     /* Kablooie! */
  438.     Boom (target[t].pos, 1.0);
  439.     if (!am_server) DestroyTarget (t);
  440.     if (am_server) target[t].shields = 100.0;
  441.   }
  442.   DestroyMissile (m);
  443. }
  444.